/*
 * Copyright (c) 2007 Ulrich Hilger, http://dev.uhilger.de, all rights reserved.
 *
 * Published under the terms and conditions of the Apache License 2.0,
 * see http://www.apache.org/licenses/LICENSE-2.0
 */

package de.uhilger.lib.filesystem;

import java.io.Serializable;

/**
 * A reference to a file consisting of the file's absolute path and additional
 * information about whether or not the referenced file is a directory, is hidden, etc.
 * Note that FileRef only references a file, the file itself and its contents are not
 * modelled by this class.
 *
 * @author Ulrich Hilger, http://dev.uhilger.de
 * @author Published under the terms and conditions of
 * the <a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License 2.0</a>
 *
 * @version 2, 12.01.2008
 */
public class FileRef implements Serializable {

	private String absolutePath;
	private Boolean isDirectory;
	private Boolean isHidden;
	private Long lastModified;
	private Long length;

	/**
	 * create a new instance of <code>FileRef</code>. Note that the created FileRef is 
	 * only a reference to a file, the file itself will not be created.
	 * 
	 * @param absolutePath  the absolute path that denotes this instance of <code>FileRef</code>
	 * @param isDirectory  whether or not this file is a directory
	 * @param isHidden  whether or not this file is a hidden file
	 * @param lastModified  the date/time this file was last modified measured in milliseconds 
	 * 						since the epoch (00:00:00 GMT, January 1, 1970)
	 * @param length the length of this file in bytes
	 */
	public FileRef(String absolutePath, boolean isDirectory, boolean isHidden, 
			long lastModified, long length)
	{
		super();
		this.absolutePath = absolutePath;
		this.isDirectory = isDirectory;
		this.isHidden = isHidden;
		this.lastModified = lastModified;
		this.length = length;
	}
	
	/**
	 * Create a new instance of class <code>FileRef</code> with a given absolute path. 
	 * Other characteristics of the file are created with default settings 
	 * (i.e. not a directory, not hidden, unknown modification date 
	 * and length). Note that the created FileRef is only a reference to a file, the file 
	 * itself will not be created.
	 * 
	 * @param absolutePath  the absolute path that denotes this instance 
	 * of <code>FileRef</code>
	 */
	public FileRef(String absolutePath) {
		this(absolutePath, false, false, 0, 0);
	}
	
	/**
	 * Create a new instance of class <code>FileRef</code> with a given absolute path 
	 * and an indicator whether or not the new FileRef denotes a directory. 
	 * Other characteristics of the file are created with default settings 
	 * (i.e. not hidden, unknown modification date and length). Note that the created 
	 * FileRef is only a reference to a file, the file itself will not be created.
	 * 
	 * @param absolutePath  the absolute path that denotes this instance 
	 * of <code>FileRef</code>
	 * @param isDirectory  true, if the file to create should denote a directory
	 */
	public FileRef(String absolutePath, boolean isDirectory) {
		this(absolutePath, isDirectory, false, 0, 0);
	}

	/**
	 * get the absolute path that denotes this file
	 * @return  the path
	 */
	public String getAbsolutePath() {
		return absolutePath;
	}

	/**
	 * Tests whether the file denoted by this abstract pathname is a
	 * directory.
	 *
	 * @return <code>true</code> if this file is a directory, 
	 *          <code>false</code> otherwise
	 */
	public boolean isDirectory() {
		return isDirectory;
	}

	/**
	 * Tests whether the file denoted by this abstract pathname is a
	 * file.
	 *
	 * @return <code>true</code> if this file is a file, 
	 *          <code>false</code> otherwise
	 */
	public boolean isFile() {
		return !isDirectory;
	}

	/**
	 * Tests whether the file denoted by this abstract pathname is a
	 * hidden file.
	 *
	 * @return <code>true</code> if this file is a hidden file, 
	 *          <code>false</code> otherwise
	 */
	public boolean isHidden() {
		return isHidden;
	}

	/**
	 * Returns the time that this file was
	 * last modified.
	 *
	 * @return  A <code>long</code> value representing the time the file was
	 *          last modified, measured in milliseconds since the epoch
	 *          (00:00:00 GMT, January 1, 1970)
	 */
	public long getLastModified() {
		return lastModified;
	}

	/**
	 * Returns the length of this file.
	 * The return value is unspecified if this file denotes a directory.
	 *
	 * @return  The length, in bytes, of this file
	 */
	public long getLength() {
		return length;
	}
	
	/**
	 * get the name of this file without path
	 * @param separatorChar  the string that is used to separate directories and file names in 
	 * path expressions 
	 * @return the name of this file without path
	 */
	public String getName(String separatorChar) {
		String path = getAbsolutePath();
		String name = path.substring(path.lastIndexOf(separatorChar) + 1);
		if(name == null || name.length() < 1) {
			name = path;
		}
		return name;
	}

	/**
	 * get a string representation of this instance of FileRef
	 * @return the string representation of this FileRef object
	 */
	public String toString() {
		return getAbsolutePath();
	}

	/**
	 * Indicates whether some object is equal to this instance of class FileRef. Two 
	 * GenericFiles are regarded as equal when their absolute paths are equal case independently.
	 * 
	 * @param  obj  the object to compare with this instance of FileRef
	 * @return true, if obj is equal to this instance of FileRef, false if not
	 */
	public boolean equals(Object obj) {
		boolean isEqual = false;
		if(obj != null && obj instanceof FileRef) {
			isEqual = ((FileRef) obj).getAbsolutePath().toLowerCase().equals(
					this.getAbsolutePath().toLowerCase());
		}
		return isEqual;
	}	
}
